<?php
namespace classlib\imsdk;
class socket {
	private $host;
	private $port;
	private $nfd;
	
	/**
	 * 初始化设置 socket链接的必要信息
	 * @param unknown_type $host
	 * @param unknown_type $port
	 */
	public function __construct($host, $port) {
		$this->host = $host;
		$this->port = $port;
		$this->nfd  = -1;
	}
	
	/**
	 * 获取连接的socket句柄
	 * @return resource
	 */
	public function getfd() {
		return $this->nfd;
	}
	
	/**
	 * 创建socket链接
	 * 重复调用会自动关闭重连接
	 * @return 连接的标识符
	 */
	public function connect() {
		$flag = false;
		if ($this->nfd > 0) {
			socket_close($this->nfd);
		}
		$this->nfd  = socket_create(AF_INET, SOCK_STREAM, 0);
		$flag = @socket_connect($this->nfd, $this->host, $this->port);
		socket_set_option($this->nfd, SOL_SOCKET, SO_SNDTIMEO, array('sec'=>3,'usec'=>0));
		socket_set_option($this->nfd, SOL_SOCKET, SO_RCVTIMEO, array('sec'=>3,'usec'=>0));
		return $flag;
	}
	
	/**
	 * 往服务端发送socket请求
	 * @param unknown_type $msg
	 * @param unknown_type $nlen
	 * @return > 0 发送失败 =0 发送成功
	 */
	public function send($msg, $nlen) {
		do {
			$nsize = socket_write($this->nfd, $msg, $nlen);
			if ($nsize === false) {
				break;
			}
			$nlen -= $nsize;
			if ($nlen > 0) {
				$msg = substr($msg, $nsize);
			}
			
		} while ($nlen > 0);
		return $nlen;
	}
	
	/**
	 * 接收服务端的数据请求
	 * @param int $nlen
	 * @return string 空字符串说明失败
	 */
	public function revc($nlen) {
		$msg = '';
		do {
			$tmp = socket_read($this->nfd, $nlen, PHP_BINARY_READ);
			if ($tmp === false) {
				break;
			}
			$msg  .= $tmp;
			$nlen -= strlen($tmp);
		} while ($nlen > 0);
		return $msg;
	}
	
	/**
	 * 清空socket缓冲区中的脏数据
	 * @param int $nlen
	 * @return string 空字符串说明失败
	 */
	public function flush() {
		$nlen = 1024;
		$timeout = array('sec'=>1, 'usec'=>5000);
  		socket_set_option($this->nfd, SOL_SOCKET, SO_RCVTIMEO, $timeout);
		
		do {
			$msg = socket_read($this->nfd, $nlen, PHP_BINARY_READ);
			if (!$msg) {
				break;
			}
		} while (1);
	}
}